[HTML5] WebSocketでMessagePackを使う
MessagePackとは
MessagePackとは、バイナリシリアライゼーションフォーマットです。 最近はクライアント/サーバ間でデータをやりとりする場合、JSONフォーマットが非常によく使用されていますが、 WebSocketでデータの送受信をする際にもJSON.stringifyを使用してJSON文字列を使っているのではないでしょうか。 MessagePackを使用した場合、JSONにくらべて高速に動作し、データサイズもコンパクトになるという特徴があります。
今回はnode + websocketにおいてMessagePackでデータの送受信をおこなってみましょう。
環境構築方法
今回使用した動作環境は以下のとおりです。
- OS : MacOS X 10.9
- node.js : v0.10.21
- socket.io: 0.9.16
node.jsについては公式ページ等を参考にしてインストールしておいてください。 今回hサンプルで使用するプログラム用ディレクトリを作成し、npmを使用して必要なライブラリをインストールしておきましょう。
% mkdir msgPack-webSocket % cd msgPack-webSocket % npm install ws express msgpack-js
今回は、WebSocketはシンプルなwsを、MessagePackモジュールはmsgpack-jsを使用します。
WebsocketでMessagePackフォーマットデータを送信
サーバ側のプログラムを作成
まずはサーバ側のプログラムを作成します。ここでは、後に作成する画面にアクセスしたらWebSocketの接続を確立し、 固定のオブジェクト情報をMessagePackでsendしています。
//app.js var WebSocketServer = require('ws').Server , http = require('http') , express = require('express') , app = express() , msgpack = require('msgpack-js'); app.use(express.static(__dirname + '/public')); var server = http.createServer(app); server.listen(8080); //通信で使用するオブジェクト情報 var message = { name: "taro", company: "classmethod.inc", address: { country:"japan", city: "tokyo", street:'xxx' }, pthone:"xxx-xxxx-xxxx", email:"[email protected]", type:true, job: "programmer", language:["javascript","ruby","java"] }; var wss = new WebSocketServer({server: server}); wss.on('connection', function (ws) { //MessaePack形式にエンコード var sendPack = msgpack.encode(message); ws.send(sendPack, {binary: true}); ws.on('close', function () { console.log("close"); }); });
encode関数を使用することで、オブジェクトをMessagePackフォーマットに変換しています。 なお、wsモジュールでバイナリ情報のやりとりをするためには、send時にbinaryオプションをtrueにしなければなりません。
クライアント側プログラムを作成
サーバ側ではmsgpack-jsでエンコードしますが、クライアント側でデコードするためにmsgpack-javascriptを取得します。
% git clone https://github.com/msgpack/msgpack-javascript.git
次に、publicディレクトリを作成し、そこにmsgpack-javascript/msgpack.codec.jsをコピーします。 そして同じ場所にindex.htmlファイルを作成しましょう。
<!DOCTYPE html> <html> <head> <script src="msgpack.codec.js"></script> <script> function updateData(message) { document.getElementById('name').innerHTML = message.name; document.getElementById('company').innerHTML = message.company; document.getElementById('city').innerHTML = message.address.city; document.getElementById('job').innerHTML = message.job; } var host = window.document.location.host.replace(/:.*/, ''); var ws = new WebSocket('ws://' + host + ':8080'); ws.binaryType = 'arraybuffer'; ws.onmessage = function (event) { updateData(msgpack.unpack(new Uint8Array(event.data))); }; </script> </head> <body> <strong>User Data</strong><br> name:<div id='name'></div><br> company:<div id='company'></div><br> city:<div id='city'></div><br> job:<div id='job'></div><br> </body> </html>
WebSocketでうけとったデータをmsgpack#unpack関数でデコードしています。 nodeサーバを起動してlocalhost:8080にアクセスすると、MesagePack形式でサーバから取得したデータが表示されます。
まとめ
サイズを計測してみるとわかりますが、JSON.stringifyで文字列化したデータより、 MessagePack形式のデータのほうが小さくなっています。 MessagePackについては、色々と問題もありますが、大量のデータをやりとりする必要があり、少しでもデータ量を少なくしたい場合にはMessagePackを使ってみてはいかがでしょうか。
参考サイトなど
- MessagePack: msgpac-js Github: ws Github: